#!/usr/bin/env python3
import os
import json
import subprocess

#check if login attempt succeded
def check_login():
	raw_json=""
	try:
		raw_json = str(open("files.json").read())
	except FileNotFoundError:
		#json file doesn't exist (no response from server...?)
		os.system("touch fail")
		return -2

	try:
		files = json.loads(raw_json)
	except ValueError:
		print("Ok, there's a problem with your password (it's not supported). Don't worry! You can try:")
		print("  - Using an API key instead of your password (you can generate an API key on your Neocities site settings: https://neocities.org/settings/<your_username>#api_key)")
		print("      * To use an API key, use \"./push -k\" instead of just \"./push\"")
		print("  - Changing your password and avoid using characters like '!', '@' or ':'")
		print("If you tried every option listed above and this message is still shown, please report this issue: https://notabug.org/nokoru/nci/issues")
		os.system("touch fail")
		exit()

	if "error_type" in files:
		if (files["error_type"] == "invalid_auth"):
			#invalid username or password
			os.system("touch fail")
			return -1
		else:
			#any other crap
			os.system("touch fail")
			return -3
	elif "result" in files and files["result"] == "success":
		#login ok
		return 0
	else:
		#any other crap again
		os.system("touch fail")
		return -3

def init_comparison():
	#create the "to-update" list file
	remote_files = json.loads(open("files.json").read())["files"]

	for rf in remote_files:
                #nci won't try to delete your index.html or not_found.html files
                #every other file is listed for deletion by default until nci verifies its local existence
		if rf["path"] != "index.html" and rf["path"] != "not_found.html":
	                to_delete.append(rf["path"])

	#*exclude article_template.html!!
	compare_files("public_html/",remote_files)

	#delete files.json since it's no longer needed
	os.system("rm -f files.json")

#recursive file comparison
#i don't really like this function, i think i did something wrong?... "it just werks" for now, but if you can improve it, please do it!
def compare_files(dir,remote_files):
	for f in os.listdir(dir):
		#nci excludes the article template and hidden files
		if dir+f == "public_html/articles/article_template.html" or f.find('.') == 0:
			continue
		#if f is a directory, compare its files
		if os.path.isdir(dir+f):
			if (dir+f).replace("public_html/","") in to_delete:
				to_delete.remove((dir+f).replace("public_html/",""))
			compare_files(dir+f+"/",remote_files)
			continue

		#check sha1 sum of current file f
		f_sha1sum = str(subprocess.check_output(["sha1sum",dir+f])).split("  ")[0].split("b'")[1]
		#is current file f a new file?
		is_new = True
		#files that won't be deleted
		for rf in remote_files:
			if rf["path"] == (dir+f).replace("public_html/",""):
				is_new=False
				if rf["path"] in to_delete:
					to_delete.remove(rf["path"])

				if rf["sha1_hash"] != f_sha1sum:
					to_upload.append((dir+f).replace("public_html/",""))

		if is_new:
			to_upload.append((dir+f).replace("public_html/",""))

def write_lists():
	os.system("touch files.upload.list")
	os.system("touch files.delete.list")

	f_upload = open("files.upload.list","w")
	for f in to_upload:
		f_upload.write(f+'\n')
	f_upload.close()

	f_delete = open("files.delete.list","w")
	for f in to_delete:
		f_delete.write(f+'\n')
	f_delete.close()

#...
to_upload=[]
to_delete=[]
login_result = check_login()
if login_result == -1:
	os.system("rm -f files.json")
	print("Invalid username, key or password. Please check your credentials and try again. To change your username, edit the first line of the \"nci.conf\" file.")
elif login_result == -2:
	os.system("rm -f files.json")
	print("No response file from https://neocities.org/ servers. Please try again.")
elif login_result == -3:
	os.sysytem("rm -f files.json")
	print("Unknown error. Please check the response of 'curl https://<your_username>:<your_password>@neocities.org/api/list' if you want to know what's wrong.")
else:
	#create a list with files to be uploaded
	print("Successfully logged in!")
	print("Comparing files...")
	init_comparison()
	print(str(to_upload.__len__()) + " file(s) will be uploaded to Neocities.")
	print(str(to_delete.__len__()) + " file(s) will be deleted from Neocities.")
	write_lists()
